<?php
// +----------------------------------------------------------------------
// | XShop小程序商城
// +----------------------------------------------------------------------
// | Author: Peak Xin <xinyflove@gmail.com>
// +----------------------------------------------------------------------

namespace app\api\service;
use think\Exception;

/**
 * 获取和管理微信access_token
 * Class AccessToken
 * @package app\api\service
 */
class AccessToken {

    private $tokenUrl;
    const TOKEN_CACHED_KEY = 'access';// 缓存key
    const TOKEN_EXPIRE_IN = 7000;// 过期时间,微信返回的token是7200

    public function __construct()
    {
        $url = config('wx.access_token_url');
        $url = sprintf($url, config('wx.app_id'), config('wx.app_secret'));
        $this->tokenUrl = $url;
    }

    /**
     * 获取微信access_token
     *  建议用户规模小时每次直接去微信服务器取最新的token
     *  但微信access_token接口获取是有限制的 2000次/天
     * @return mixed
     */
    public function get()
    {
        $token = $this->__getFromCache();
        if(!$token){
            return $this->__getFromWxServer();
        }
        else{
            return $token;
        }
    }

    /**
     * 从缓存获取access_token
     * @return mixed|null
     */
    private function __getFromCache(){
        $token = cache(self::TOKEN_CACHED_KEY);
        if(!$token){
            return $token;
        }
        return null;
    }

    /**
     * 从微信获取access_token
     * @return mixed
     * @throws Exception
     */
    private function __getFromWxServer()
    {
        $token = curl_get($this->tokenUrl);
        $token = json_decode($token, true);
        if (!$token)
        {
            throw new Exception('获取AccessToken异常');
        }
        if(!empty($token['errcode'])){
            throw new Exception($token['errmsg']);
        }
        $this->__saveToCache($token);
        return $token['access_token'];
    }

    /**
     * 保存access_token到缓存
     * @param $token
     */
    private function __saveToCache($token){
        cache(self::TOKEN_CACHED_KEY, $token, self::TOKEN_EXPIRE_IN);
    }
}